PHP sessies
Home

PHP sessies

PHP sessies

Stateful webapplicaties, die de informatie over een bepaalde bezoeker bijhouden zolang die doorheen de site navigeert, is tegenwoordig vanzelfsprekend.

Probleem

HTTP, het protocol dat webservers en -clients gebruiken om met elkaar te praten , is per definitie een stateless protocol. PHP beschikt echter over een handige set van sessie managementfuncties die het implementeren van statefulness eenvoudig maakt.

Oplossing

In dit artikel laten we zien hoe je sessies kan gebruiken om gebruikersgegevens bij te houden met PHP.

Dit is een krachtig concept omdat sessiegegevens op de webserver kunnen worden opgeslagen. Dus als een gebruiker klikt en naar een andere pagina gaat (stateless), heeft de server nog steeds de informatie over de gebruiker (statefulness).

Vrijwel elke site met een inlogsysteem waar een gebruiker inlogt, zal sessies gebruiken. Zodra een gebruiker is ingelogd, wordt een sessie gestart. Als de gebruiker naar een andere pagina gaat of zelfs van de site naar een andere gaat en terugkomt, zijn hun gegevens nog steeds beschikbaar, zodat ze verder kunnen gaan waar ze waren gebleven.

Dus hoe werken sessies en hoe kunnen we ze implementeren op een website met PHP?

Session Tracking: gebruikersgegevens bijhouden

Met sessies kan je variabelen aanmaken die blijven bestaan tussen de aanvragen. Om met sessies te kunnen werken moet elke request van de gebruiker een unieke session-id bevatten die op unieke wijze een sessie identificeert. Alleen een unieke id wordt opgeslagen aan de client zijde. Deze session-id wordt doorgegeven aan de webserver telkens wanneer de browser een HTTP-aanvraag (d.w.z. een link naar de pagina of een AJAX verzoek maakt). De webtoepassing zal die session-id in haar interne database opzoeken en de opgeslagen variabelen voor gebruik door de desbetreffende webpagina ophalen.

We illustreren dat met een voorbeeld. We maken een eenvoudig aanmeldingsformulier waarin we vragen naar de gebruikersnaam met een Aanmelden knop. Als de pagina wordt geladen kijken we eerst als de gebruikersnaam al is verzonden. Als dat het geval is halen we die op uit de sessie en groeten we de aangemelde gebruiker. We zetten daarvoor de volgende stappen:

  1. stateless
    1. We hergebruiken de index.php uit PHP cookies:
      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport"
                content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
          <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <title>Werken met cookies en sessies - logging in</title>
      </head>
      <body>
      <form class="logging-in" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="POST">
          <div class="field">
              <label for="user-name">Gebruikersnaam: </label>
              <input id="user-name" name="user-name" class="text" type="text" required/>
          </div>
          <button type="submit" name="submit" id="login" value="login">Aanmelden</button>
      </form>
      <h1>Welkom</h1>
      
      <?php
      if (isset($userName)) { ?>
          <p><?php echo $userName; ?></p>
          <form class="logging-out" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="POST">
              <button type="submit" name="submit" id="logout" value="logout">Afmelden</button>
          </form>
          <a href="catalog.php">Ga naar boekencataloog</a>
          <?php
      }
      ?>
      </body>
      </html>
    2. Wanneer je echter de pagina opnieuw laadt in de browser, door bijvoorbeeld op de Aanmelden knop te drukken, is de ingetypte gebruikersnaam verdwenen, die wordt tussen de eerste en de tweede keer dat de pagina geladen wordt niet bewaard. Dat is de betekenis van stateless:
      PHP stateless Aanmelden oefening cookie en session
      PHP stateless Aanmelden oefening session
  2. statefulness
    Om de ingetypte waarden tusen de eerste en de volgende keren dat de pagina wordt geladen wel te bewaren gebruiken we een session. We zetten daarvoor de volgende stappen:
    1. we maken een session.php bestand in de include map;
    2. session-start
      Om een sessie te starten die gebruikers- of gebruikersgegevens kan traceren, moet je een sessie starten met de functie session_start. Dat statement moet het eerste statement zijn, helemaal bovenaan, direct na de <?php openingstag. Anders krijg je de foutmelding Headers already sent. Als je nog steeds dezelfde foutmelding krijgt, sla dan je PHP-bestand op in de ANSI-codering. Meer dan waarschijnlijk is het PHP-bestand opgeslagen in Unicode-, Unicode Big Endian- of UTF-8-codering. Dit soort coderingen voegen onzichtbare tekens aan het begin van een bestand die de foutmelding veroorzaakt:
      <?php
      session_start();
      
      1. Om dat uit te proberen gebruiken we de index.php die gemaakt hebben in PHP cookies. I.p.v. include/cookies-index.php in te sluiten, sluiten we include/session.php in. De index.php ziet er dan zo uit:
        <?php
        include('include/session.php');
        ?>
        <!doctype html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport"
                  content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <title>Werken met cookies en sessies - logging in</title>
        </head>
        <body>
        <form class="logging-in" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="POST">
            <div class="field">
                <label for="user-name">Gebruikersnaam: </label>
                <input id="user-name" name="user-name" class="text" type="text" required/>
            </div>
            <button type="submit" name="submit" id="login" value="login">Aanmelden</button>
        </form>
        <h1>Welkom <?php echo isset($userName) ? $userName : '';?></h1>
        
        <?php
        if (isset($userName)) { ?>
            <form class="logging-out" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="POST">
                <button type="submit" name="submit" id="logout" value="logout">Afmelden</button>
            </form>
            <a href="catalog.php">Ga naar boekencataloog</a>
            <?php
        }
        ?>
        </body>
        </html>
      2. Als we de index.php pagina in de browser laden zorgt de functie session_start ervoor dat er een sessiecookie wordt gemaakt met de naam PHPSESSID:
        PHP startsession PHPSESSID cookie
        PHP startsession PHPSESSID cookie
      3. Een session gebruikt een cookie om de naam van het sessiesbestand mee door te geven van de ene naar de andere pagina. Dus hier moeten we rekening houding met de risico's die cookies met zich meebrengen. Zie hiervoor PHP cookiekaping en andere risicos.

        1. we halen eerst de instellingen op zoals die in het php.ini bestand zijn gedefinieerd;

        2. we maken een $options array die een combinatie is van waarden uit het php.ini bestand en locale instellingen;

        3. we herdefiniëren de settings voor sessiecookie van deze sessie;
          1$cookieParams = session_get_cookie_params();
          2$options = array('lifetime' => $cookieParams["lifetime"],
              'path' => '/',
              'domain' => '',
              'secure' => true,
              'httponly' => true,
              'samesite' => 'Strict');
          3session_set_cookie_params($options );
        4. We kunnen de instellingen visualiseren met:
          session_start();
          phpinfo();
          
          We zien dat de globale waarden overschreven zijn met lokale:

          session

          Session Support enabled
          Registered save handlers files user
          Registered serializer handlers php_serialize php php_binary
          Directive Local Value Master Value
          session.cache_expire 180 180
          session.cache_limiter nocache nocache
          session.cookie_domain no value no value
          session.cookie_httponly 1 no value
          session.cookie_lifetime 0 0
          session.cookie_path / /
          session.cookie_samesite Strict no value
    3. session_name
      De functie session_name geeft de naam van de huidige sessie terug. Als een naam is opgegeven, zal session_name de sessienaam bijwerken en de oude sessienaam retourneren.

      Als een nieuwe sessienaam wordt opgegeven, wijzigt session_name de HTTP-cookie.
      De functie session_name moet worden aangeroepen vóór session_start om de sessie correct te laten werken.

      De sessienaam wordt bij het opstarten van het verzoek teruggezet naar de standaardwaarde die is opgeslagen in session.name in het ini.php bestand. Je moet dus session_name aanroepen voor elk verzoek (en voordat session_start wordt aangeroepen). In ons voorbeeld veranderen we de sessienaam:
      <?php
      session_name('Programmeren4');
      session_start();

      De cookienaam is nu aangepast:

      PHP startsession Programmeren4 cookie
      PHP startsession Programmeren4 cookie
    4. Waar worden sessies op de server opgeslagen?
      Er zijn 3 manieren om erachter te komen:
      1. open php.ini en zoek naar session.save_path
      2. schrijf de volgende code in het php-bestand en voer het uit:
        <?php 
        phpinfo();
        ?>
        
        Het retourneert een overzicht van de ini settings en ook van de sessieinstellingen. Let erop dat:

        session

        Session Support enabled
        Registered save handlers files user
        Registered serializer handlers php_serialize php php_binary
        Directive Local Value Master Value
        session.lazy_write On On
        1session.name Programmeren4 PHPSESSID
        session.referer_check no value no value
        session.save_handler files files
        2session.save_path no value no value
        session.serialize_handler php php
        1. dat de eigen gekozen sessienaam in de Local Value kolom staat
        2. dat er nog geen pad is opgegeven waar de sessies op de server worden opgeslagen
      3. als er geen pad is opgegeven worden de sessies bestanden in Windows opgeslagen in de AppData/Local/Temp map van de gebruiker. Op mijn computer is dat C:\Users\jefin\AppData\Local\Temp. De cookie aangemaakt hierboven staat in deze map:
        PHP sessionbestand locatie
        PHP sessionbestand locatie
      4. schrijf de volgende code in het php-bestand en voer het uit
        < php 
        echo session_save_path();?>
        
        Het retourneert het pad dat wordt gebruikt voor het opslaan van de sessiegegevens.
      5. om de sessiebestanden in een andere map te bewaren:
        <?php
        session_name('Programmeren4');
        session_save_path('c:\temp');
        session_start();

        Je vindt het sessiebestand nu in de map c:\temp:

        PHP sessionbestand in opgegeven map
        PHP sessionbestand in opgegeven map
    5. session_status
      Hiermee kunnen we nagaan als er een sessie actief is. Er zijn 3 mogelijke retourwaarden:
      1. PHP_SESSION_DISABLED als sessies zijn uitgeschakeld;

      2. PHP_SESSION_NONE als sessies zijn ingeschakeld, maar er geen bestaat;

      3. PHP_SESSION_ACTIVE als sessies zijn ingeschakeld en er een bestaat;

    6. $_SESSION gebruiken
      <?php
      1session_name('Programmeren4');
      2session_start();
      3if (session_status() === PHP_SESSION_ACTIVE) {
      4    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
      5        if (isset($_POST['submit'])) {
      6            if ($_POST['submit'] === 'login') {
                      6.1$_SESSION['userName'] = $_POST['user-name'];
                  }
      7        } elseif ($_POST['submit'] === 'logout') {
              }
          }
       }
      8$userName = isset($_SESSION['userName']) ? $_SESSION['userName'] : null;
      1. we gegeven een eigen sessienaam op;

      2. eerst voeren we de session_start-functie uit;

      3. we gebruiken de session_status functie om na te gaan als er een sessie actief is;

      4. we gaan na of er POST request verstuurd is;

      5. vervolgens verifiëren we als er op een submit knop is gedrukt. Indien dit geval is verifiëren we op welke knop er geklikt werd

      6. indien het de login knop is:

        1. bewaren we de gebruikersnaam, die de gebruiker in het formulier heeft ingevoerd, in het sessiebestand. We stoppen deze opgehaalde waardin in de $ _SESSION array. We gebruiken de waarden van het name attribuut van het HTML-tekstvak waarin de gebruikersnaam getypt werd en geven die als index mee aan de superglobal-array $_POST om de gegevens op te halen.

      7. we voorzien het geval dat er op de logout knop is geklikt maar vervolledigen dit later;
      8. tenslotte stoppen we de waarde van $_SESSION['userName'] in de variable $userName die later in het form element gebruikt zal worden;
    7. Voer het index.php bestand uit en open nadat je je hebt aangemeld, het sessiebestand C:\Users\jefin\AppData\Local\Temp\sess_nk52tla7750d5o391ppl566i9r met Kladblok:
      PHP session - inhoud sessiebestand in Kladblok
      PHP session - inhoud sessiebestand in Kladblok
    8. Omdat sessievariabelen op de server worden opgeslagen, zijn onze sessievariabelen nog steeds beschikbaar, zelfs als de gebruiker naar een andere pagina gaat. Daarom kunnen we gebruikers van pagina tot pagina tot pagina volgen. Omdat te illustreren passen we de catalog.php aan zodat die nu ook met sessies werkt:
      <?php
      include('include/session.php');
      ?>
      <!doctype html>
      <html lang="nl">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport"
                content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
          <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <title>Boekencataloog - werken met cookies en sessies</title>
      </head>
      <body>
      <h1>Boekencataloog</h1>
      <h2>Welkom <?php echo isset($userName) ? $userName : 'Je bent niet aangemeld.'; ?></h2>
      <p>Je bestellingen:</p>
      <p><?php echo isset($shoppingCart) ? $shoppingCart : 'Nog geen boeken besteld.'; ?></p>
      <button type="submit" name="shopping-cart" id="empty" value="empty"
              form="catalog-form">Winkelkar leegmaken
      </button>
      <h3>Bestel een boek</h3>
      <form method="post" id="catalog-form" name="catalog-form"
            action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
          <div>
              <label for="book-1">Herman Portocarero, De zwarte handel</label>
              <button id="book-1" name="order" value="Herman Portocarero, De zwarte handel">Bestel</button>
          </div>
          <div>
              <label for="book-2">Aristophanes, Ploutos de god van het geld</label>
              <button id="boek-2" name="order" value="Aristophanes, Ploutos de god van het geld">Bestel</button>
          </div>
          <div>
              <label for="book-3">Steve Prettyman, Learn PHP 8</label>
              <button id="prettyman" name="order" value="Steve Prettyman, Learn PHP 8">Bestel</button>
          </div>
          <div>
              <label for="daudet">Alphonse Daudet, Brieven uit mijn molen</label>
              <button id="daudet" name="order" value="Alphonse Daudet, Brieven uit mijn molen">Bestel</button>
          </div>
      </form>
      <a href="index.php">Terug naar de index pagina</a>
      </body>
      </html>

      Voer het index.php bestand uit en meld je aan als je dat nog niet gedaan hebt:

      session wellcome.php
      session wellcome.php

      Klik op de link Ga naar boekencataloog en je ziet dat de gebruikersnaam mee wordt doorgegeven en nog altijd gekend is:

      session catalog wellcome.php
      session catalog wellcome.php
    9. Een sessie beëindigen
      Een sessie eindigt wanneer een gebruiker de browser sluit of soms zelfs wanneer een gebruiker naar een website gaat. Maar als je een sessie met PHP definitief wilt beëindigen, dan kun je de session_destroy functie gebruiken. Dit beëindigt de sessie van een gebruiker, d.w.z. de gebruiker zal niet langer worden gevolgd.
      1. in include/session.php kijk je na of de gebruiker op de logout knop heeft geklikt, indien dit het geval is:
        1. maak de $_SESSION array leeg
        2. haal de session_cookie parameters op;
        3. zet de expires sleutel in op een tijdstip in het verleden en de rest neem je over van de bestaande instellingen;
        4. verwijder de cookie door die opnieuw in te stellen met een negatieve datum;
        5. gebruik de session_destroy functie om het session bestand te verwijderen op de server;
      <?php
      session_name('Programmeren4');
      // session_save_path('c:\temp');
      // Gets current cookies params
      $cookieParams = session_get_cookie_params();
      $options = array('lifetime' => $cookieParams["lifetime"],
          'path' => '/',
          'domain' => '',
          'secure' => true,
          'httponly' => true,
          'samesite' => 'Strict');
      session_set_cookie_params($options);
      session_start();
      // phpinfo();
      if (session_status() === PHP_SESSION_ACTIVE) {
          if ($_SERVER['REQUEST_METHOD'] === 'POST') {
              if (isset($_POST['submit'])) {
                  if ($_POST['submit'] === 'login') {
                      $_SESSION['userName'] = $_POST['user-name'];
                  }
      1        } elseif ($_POST['submit'] === 'logout') {
                  // Unset all session values
                  1.1$_SESSION = array();
                  // get session parameters
                  1.2$cookieParams = session_get_cookie_params();
                  // Delete the actual cookie.
                  1.3$options = array('expires' => time() - 42000,
                      'path' => $cookieParams['path'],
                      'domain' => $cookieParams['domain'],
                      'secure' => $cookieParams['secure'],
                      'httponly' => $cookieParams['httponly'],
                      'samesite' => $cookieParams['samesite']);
                  1.4setcookie(session_name(), '', $options);
                  // Destroy session
                  1.5session_destroy();
              }
          }
      }
      $userName = isset($_SESSION['userName']) ? $_SESSION['userName'] : null;

Sessions en veiligheidsrisico's

  1. Standaard accepteert PHP een sessie-id, die in een cookie wordt verzonden. Maar als session.use_only_cookies is ingesteld op 1, zal er geen een sessie-id geaccepteerd worden die in de URL verstuurd wordt.
    Een aanvaller kan een bezoeker verleiden om een koppeling te volgen naar je applicatie die gebruik maakt van een ingesloten sessie-id:
    <a href="http://example.org/login.php?PHPSESSID=1234">Click Here!</a>

    Een gebruiker, die op deze link klikt, zal de sessie met id 1234 hervatten. De aanvaller kent nu sessie-id van de gebruiker en kan proberen de sessie van de gebruiker te kapen door de dezelfde sessie-id aan de server te presenteren.
    PHP beschikte over een terugvalmechanisme voor gebruikers die cookies niet konden of weigerden te accepteren. In dit geval werd de sessie-id op de een of andere manier toegevoegd aan elke (!) URL. Tegenwoordig accepteert bijna iedereen cookies (in ieder geval sessiecookies), aangezien elke website ze gebruikt en hebben we dat terugvalmechanisme niet meer nodig.

  2. De session_start() functie initialiseert een sessie en je kan key-pair values in de superglobal $_SESSION array manipuleren om informatie over de gebruiker op te slaan:

    session_start();
    if (! isset($_SESSION['visits'])) {
        $_SESSION['visits'] = 0;
    }
    $_SESSION['visits']++;
    print 'You have visited here '.$_SESSION['visits'].' times.';

    De sessies module onthoudt informatie over gebruikers door hen cookies te sturen met willekeurig gegenereerde sessie-id's.

    1. PHP slaat standaard sessiegegevens op in bestanden in de /tmp directory op je server.

    2. Elke sessie wordt opgeslagen in een eigen bestand.

    3. Als je de map wilt wijzigen waarin de bestanden zijn opgeslagen, stel je de session.save_path configuratie richtlijn in op de nieuwe map waarin je de bestanden wilt opslaan. Dat kan in het php.ini bestand of met ini_set(). Je kan ook de methode session_save_path() gebruiken een een nieuwe map map als argument meegeven. Doe dit voaaleer een sessie te starten of een met sessievariabele te werken.

    4. Om een sessie bij elke request automatisch op te starten kan je de session.auto_start richtlijn in php.ini instellen op 1. Als je de mogelijkheid hebt om je php.ini bestand te wijzigen, is dat het eenvoudigste.

  3. Als de session.use_trans_sid configuratie richtlijn is ingeschakeld, zal PHP automatisch de sessie-ID aan URL's en formulieren toevoegen wanneer PHP detecteert dat een gebruiker de sessie ID cookie niet accepteert.

    Bijvoorbeeld, deze code print een URL worden:

    print '<a href="train.php">Ga naar start</a>';

    Als sessies zijn ingeschakeld maar de gebruikt accepteert geen cookies wordt het volgende naar de brower gestuurd:

    <a href="train.php?PHPSESSID=2eb89f3344520d11969a79aea6bd2fdd">Ga naar start/a>

    In dit voorbeeld, is de sessienaam PHPSESSID en de naam van de sessie-ID is 2eb89f3344520d11969a79aea6bd2fdd. PHP voegt die naar de URL, zodat ze worden doorgegeven naar de volgende pagina. Formulieren worden gewijzigd en er wordt een verborgen element toegevoegd dat de sessie-ID doorgeeft.

    Omwille van veiligheidsredenen worden het transparant doorsturen van sessie-id's op de URL's standaard uitgeschakeld. Als je dat toch wilt doen moet je de configuratierichtlijn session.use_trans_sid in php.ini instellen of met gebruik van ini_set ('ses sion.use_trans_sid', true) in je script vooraleer de sessie te starten.

    Hoewel session.use_trans_sid handig kan zijn, is het een onveilige manier van werken. Omdat URL's een sessie-id's bevatten, kan het verspreiden van een dergelijke een URL voor problemen zorgen. Iedereen die de URL ontvangt, kan als de gebruiker van wie de sessie-ID is, optreden. Een gebruiker die een URL vanuit zijn webbrowser kopieert en in een e-mailbericht plakt en die email verzend naar vrienden geeft onbewust aan al die vrienden (en iedereen aan wie het bericht is doorgestuurd) de mogelijkheid met zijn session id naar de desbetreffende website te gaan en bijvoorbeeld daar aankopen te doen.

    What’s worse, when a user clicks a link on your site that takes him to another site, the user’s browser passes along the session ID–containing URL as the referring URL to the external site. Even if the folks who run that external site don’t maliciously mine these referrer URLs, referrer logs are often inadvertently exposed to search engines. Search for “PHPSESSID referer” on your favorite search engine, and you’ll probably find some referrer logs with PHP session IDs embedded in them.

    Separately, redirects with the Location header aren’t automatically modified, so you have to add a session ID to them yourself using the SID constant:

    $redirect_url = 'http://www.example.com/airplane.php';
    if (defined('SID') && (!isset($_COOKIE[session_name()]))) {
        $redirect_url .= '?' . SID;
    }
    header("Location: $redirect_url");

    De functie session_name() retourneert de naam van de cookie die de sessie-ID oplsaat. Op die manier voegt deze code de SID constante toe aan $redirect_url als de constante is gedefinieerd, en de sessie-cookie is niet ingesteld.

  4. Cross Site Scripting (XSS) Attacks: Methodology and Prevention
    To reduce the chances of your application falling victim to an attack, it's essential that any Web application development is undertaken using a "security development lifecycle" approach. The aim of the security development lifecycle is to reduce the number of security-related design and coding defects, and to reduce the severity of any defects that do remain undetected.
    As part of this process, you should incorporate threat modeling. Performed during the application design stage, threat modeling identifies and evaluates the risks to an application. In order to identify potential threats to the application, assets must be categorized, along with sensitive information that the application accesses. Threat modeling not only raises security awareness among developers, but also makes security an integral part of the application design and development process. By having security professionals and developers work together, it's easier to analyze an application from an attacker's point of view. For more help, download Microsoft's free Threat Modeling Tool.
  5. Sessiekaping
    1. Probleem
      Je wil voorkomen dat een mogelijke aanvaller geen toegang krijgt tot de sessie van een andere gebruikers.
    2. Design

      Beperk het doorgeven van sessie-id's tot cookies alleen en genereer een extra sessie-token dat wordt doorgegeven via URL's.

      Alleen aanvragen die een geldige sessie-ID en een geldige sessie token bevatten kunnen toegang krijgen tot de sessie:

      ini_set('session.use_only_cookies', true);
      session_start();
      $salt = 'YourSpecialValueHere';
      $tokenstr = strval(date('W')) . $salt;
      $token = md5($tokenstr);
      if (!isset($_REQUEST['token']) || $_REQUEST['token'] != $token) {
          // prompt for login
      exit;
      }
      $_SESSION['token'] = $token;
       
      output_add_rewrite_var('token', $token);

      In dit voorbeeld wordt een zichzelf aanpassende token gemaakt door het huidige week nummer en een zoutstring toe te voegen.

      Met deze techniek is het token geldig voor een redelijke termijn zonder vast te liggen. Het zout voorkomt dat iemand uit de berekening van hun eigen MD5 hash van een datum ver in de toekomst berekent en de het gebruik van de sessie eindeloos uitbredit.

      Zonder het 'zout' te kennen is het niet gemakkelijk van een geldig token te maken. We controleren vervolgens het token in de aanvraag, en als het niet wordt gevonden, vragen we om een nieuwe login. Als het wel wordt gevonden, moet het worden toegevoegd aan gegenereerde links. Dat kan gemakkelijk met output_add_rewrite_var().

      Merk op dat dit mechanisme de site niet beveiligd tegen een aanvaller die al het verkeer tussen een gebruiker en de server (bijvoorbeeld, op een niet-versleutelde wifinetwerk) kan sniffen. Het runnen van je site via SSL is de beste manier om dat soort aanval te voorkomen.

  6. Sessie fixatie: Preventing Session Fixation
    1. Probleem

      We willen ervoor zorgen dat onze toepassing niet kwetsbaar voor is sessie fixatie aanvallen waarbij een aanvaller een gebruiker dwingt om een vooraf bepaalde sessie-ID te gebruiken.

      Deze twee voorzorgsmaatregelen elimineren vrijwel het risico van sessie fixatie omdat een sessie-ID zo vaak verandert, en omdat sessies id's kunnen alleen worden doorgegeven in de cookies.

    2. Design

      Vereist het gebruik van sessiecookies zonder dat de sessie-id toegevoegd wordt aan de URL's, en het vaak genereren van een nieuwe sessie-ID.

      We beginnen met PHP te vertellen alleen cookies te gebruiken voor sessies. Dit zorgt ervoor dat PHP geen aandacht zal besteden aan een sessie-ID die meekomt in een URL.

      Zodra de sessie is gestart, stellen we een waarde in die bijhoudt wanneer de laatste keer een sessie-ID werd gegenereerd. Door regelmatig een nieuwe ID te genereren — om de 30 seconden in dit voorbeeld — is de kans klein dat een aanvaller een geldige sessie ID verkrijgt.

      ini_set('session.use_only_cookies', true);
      session_start();
      if (!isset($_SESSION['generated']) || $_SESSION['generated'] < (time() - 30)) {
          session_regenerate_id();
          $_SESSION['generated'] = time();
      }

      Deze twee voorzorgsmaatregelen elimineren vrijwel het risico van sessie fixatie omdat een sessie-ID zo vaak verandert, en omdat sessies id's kunnen alleen worden doorgegeven in de cookies.

      Zie ook: “Session Fixation Vulnerability in Web-based Applications”; Recipe 18.1 for information about regenerating session IDs on privilege escalation

  7. XXS
    1. Probleem
      Een manier om de website tegen XSS te beschermen bestaat erin alle HTML of andere speciale karacters uit de input string (cookie, gebruikersinput enz.) te verwijderen.
    2. Oplossing

      De UserId die we gebruiken is een positief geheel getal. Dus maken we een setter alleen een positief geheel getal instelt.

      public function setPositiveInteger($key, $value)
      {
      // XSS protection as we might print this value
           $_SESSION[$key] = preg_replace("/[^0-9]+/", "", $value);
      }

Bronnen

  1. Lukas Rossi, How to Harden Your PHP for Better Security, July 24, 2018
    PHP is widely used among many sites & applications, but should be hardened for security. Here’s some advanced tips to secure your PHP configuration file.
  2. Alex Web Develop, PHP Sessions explained, A BASIC AND COMPLETE INTRODUCTION TO PHP SESSIONS, Mar 19, 2018
    Met ook andere interessante artikels over PHP!

  3. Robert Hafner, How to Create Bulletproof Sessions, September 1, 2009

JI
2021-05-05 07:54:43